package gdou.gym.service.space.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import gdou.gym.dao.*;
import gdou.gym.entity.*;
import gdou.gym.exception.StateCode;
import gdou.gym.exception.SysException;
import gdou.gym.returnvo.UserQueryInfoVo;
import gdou.gym.service.space.SpaceService;
import gdou.gym.sys.order.Remain;
import gdou.gym.vo.Ask4SpaceVo;
import gdou.gym.vo.MyPageInfo;
import gdou.gym.vo.SpaceAndTimeVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SpaceServiceImpl implements SpaceService {
    @Resource
    private SpaceMapper spaceMapper;
    @Resource
    private SpaceTimeMapper spaceTimeMapper;
    @Resource
    private SpaceViewMapper spaceViewMapper;
    @Resource
    private SiteApplicationMapper siteApplicationMapper;
    @Resource
    private OrderViewMapper orderViewMapper;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private Remain remain;

    @Override
    public SiteApplication ask4Space(SiteApplication request) {
        Integer remain = this.remain.getRemain(request.getSpaceId());
        if (remain == null || remain <= 0) throw new SysException(StateCode.ORDER_ERROR);
        siteApplicationMapper.insert(request);
        this.remain.request(request.getSpaceId());
        return request;
    }

    @Override
    public void updateSiteApplication(SiteApplication request) {
        SiteApplication key = siteApplicationMapper.selectByPrimaryKey(request.getId());
        if (key.getStatus() != 0) throw new SysException(StateCode.PARAMS_ERROR);
        if (request.getStatus() == 2) {
            remain.recover(request.getSpaceId());
            siteApplicationMapper.updateByPrimaryKey(request);
        } else {
            try {
                List<String> list = orderViewMapper.queryCancelOrderByRequest(request.getSite(), request.getDate(), request.getTime());
                if (!list.isEmpty()) {
                    OrdersExample example = new OrdersExample();
                    example.createCriteria().andNoIn(list);
                    Orders record = new Orders();
                    record.setState(true);
                    System.out.println(ordersMapper.updateByExampleSelective(record, example));
                }
                siteApplicationMapper.updateByPrimaryKey(request);
            } catch (RuntimeException e) {
                e.printStackTrace();
                request.setStatus(2);
                siteApplicationMapper.updateByPrimaryKey(request);
                throw new SysException(StateCode.UPDATE_ERROR);
            }
        }

    }

    @Override
    public void removeSpaceById(Integer id) {
        remain.remove(id);
    }

    @Override
    public void updateSpaceRemain(Integer id, Integer remain) {
        this.remain.put(id, remain);
    }

    @Override
    public List<String> getSiteType() {
        List<String> name = spaceMapper.getName();
        Collections.sort(name);
        return name;
    }

    @Override
    public List<SpaceView> queryByCondition(MyPageInfo<UserQueryInfoVo> vv, boolean containZero) {
        SpaceViewExample spaceViewExample = new SpaceViewExample();
        UserQueryInfoVo vo = vv.getQueryInfo();
        SpaceViewExample.Criteria criteria = spaceViewExample.createCriteria();
        if (vo.getCost() != null) criteria.andCostLessThanOrEqualTo(vo.getCost());
        if (vo.getName() != null) criteria.andNameEqualTo(vo.getName());
        if (vo.getTime() != null) criteria.andTimeEqualTo(vo.getTime());
        if (vo.getData() != null) criteria.andDataEqualTo(vo.getData());
        if (!containZero) criteria.andRemainGreaterThan(0);
        PageHelper.startPage(vv.getPageNo(), vv.getPageSize());
        List<SpaceView> list = spaceViewMapper.selectByExample(spaceViewExample);
        Iterator<SpaceView> iterator = list.iterator();
        while (iterator.hasNext()) {
            SpaceView next = iterator.next();
            next.setRemain(remain.getRemain(next.getId()));
            if (next.getRemain() == null) iterator.remove();
        }
        return list;
    }

    @Override
    public List<String> getSiteTime() {
        List<String> time = spaceTimeMapper.getTime();
        Collections.sort(time);
        return time;
    }


    @Override
    @Transactional
    public void addNewSpace(SpaceAndTimeVo spaceAndTimeVo) {
        try {
            SpaceTime spaceTime = new SpaceTime(spaceAndTimeVo);
            Space space = new Space(spaceAndTimeVo);
            spaceMapper.insert(space);
            spaceTimeMapper.insert(spaceTime);
            remain.putOrIncrease(spaceTime.getId(), spaceTime.getRemain());
        } catch (RuntimeException e) {
            throw new SysException(StateCode.ADD_ERROR);
        }
    }


    @Override
    public PageInfo<SiteApplication> queryMyAsk(String applicant) {
        SiteApplicationExample example = new SiteApplicationExample();
        example.createCriteria().andApplicantEqualTo(applicant);
        PageInfo<SiteApplication> info = new PageInfo<>(siteApplicationMapper.selectByExample(example));
        if (info.getList().isEmpty()) return info;
        merge(info.getList());
        return info;
    }

    private void merge(List<SiteApplication> list) {
        SpaceViewExample ee = new SpaceViewExample();
        ee.createCriteria().andIdIn(list.stream().map(SiteApplication::getSpaceId).collect(Collectors.toList()));
        List<SpaceView> views = spaceViewMapper.selectByExample(ee);
        HashMap<Integer, SpaceView> map = new HashMap<>();
        for (SpaceView view : views) {
            map.put(view.getId(), view);
        }
        for (SiteApplication application : list) {
            application.update(map.get(application.getSpaceId()));
        }

    }

    @Override
    public PageInfo<SiteApplication> queryAskByCondition(MyPageInfo<Ask4SpaceVo> vo) {
        Ask4SpaceVo info = vo.getQueryInfo();
        SiteApplicationExample example = new SiteApplicationExample();
        SiteApplicationExample.Criteria criteria = example.createCriteria();
        if (info.getStatus() != null) criteria.andStatusEqualTo(info.getStatus());
        if (info.getApplicant() != null) criteria.andApplicantEqualTo(info.getApplicant());
        if (info.getBegin() != null) criteria.andTimestampGreaterThanOrEqualTo(info.getBegin());
        if (info.getEnd() != null) criteria.andTimestampLessThanOrEqualTo(info.getEnd());
        PageHelper.startPage(vo.getPageNo(), vo.getPageSize());
        PageInfo<SiteApplication> pageInfo = new PageInfo<>(siteApplicationMapper.selectByExample(example));
        if (pageInfo.getList().isEmpty()) return pageInfo;
        merge(pageInfo.getList());
        return pageInfo;
    }
}
